package com.wzm.basic.service.impl;

import com.wzm.basic.constant.VerifyCodeConstant;
import com.wzm.basic.domain.SmsDto;
import com.wzm.basic.exception.BusinessException;
import com.wzm.basic.service.VerifyCodeService;
import com.wzm.basic.util.StrUtils;
import com.wzm.basic.util.VerifyCodeUtils;
import com.wzm.user.domain.User;
import com.wzm.basic.dto.VerifyCodeDto;
import com.wzm.user.mapper.UserMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements VerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;

    @Override
    public String getImgCode(String key) {
        //获取随机字符串
        String strCode = StrUtils.getComplexRandomString(4);
        //将随机字符串存入redis缓存，设置过期时间
        redisTemplate.opsForValue().set(key, strCode, 5, TimeUnit.MINUTES);
        //将字符串与图片合并
        String imgCode = VerifyCodeUtils.verifyCode(110, 40, strCode);

        return imgCode;
    }

    @Override
    public void smsCode(VerifyCodeDto verifyCodeDto) {
        String phone = verifyCodeDto.getPhone();
        String imageCode = verifyCodeDto.getImageCode();
        String imageCodeKey = verifyCodeDto.getImageCodeKey();
        //判空
        if (StringUtils.isEmpty(phone)) {
            throw new BusinessException("请输入手机号码");
        }
        if (StringUtils.isEmpty(imageCode)) {
            throw new BusinessException("请输入图形验证码");
        }
        if (StringUtils.isEmpty(imageCodeKey)) {
            throw new BusinessException("请重新获取图形验证码");
        }

        User user = userMapper.loadByPhone(phone);
        if (user != null) {
            throw new BusinessException("该手机号码已被注册");
        }

        Object imgObj = redisTemplate.opsForValue().get(imageCodeKey);
        if (imgObj == null) {
            throw new BusinessException("图形验证码过期");
        }
        if (!imgObj.toString().equalsIgnoreCase(imageCode)) {
            throw new BusinessException("图形验证码错误");
        }

        Object smsObj = redisTemplate.opsForValue().get(VerifyCodeConstant.REGISTER_CODE_PREFIX + phone);
        String smsCode = null;
        if (smsObj == null) {
            smsCode = StrUtils.getRandomString(4);
        } else {
            long nowTime = System.currentTimeMillis();
            String oldTimeTemp = smsObj.toString().split(":")[1];
            long oldTime = Long.parseLong(oldTimeTemp);

            if ((nowTime - oldTime) < 1 * 60 * 1000) {
                throw new BusinessException("操作频繁，请稍后重试");
            } else {
                smsCode = smsObj.toString().split(":")[0];
            }
        }

        redisTemplate.opsForValue().set(VerifyCodeConstant.REGISTER_CODE_PREFIX + phone, smsCode + ":" + System.currentTimeMillis(), 3, TimeUnit.MINUTES);
        //发短信
        //SmsUtil.sendSms(phone, "你的验证码为：" + smsCode + "，请在3分钟之内使用!" );  //有次数
        System.out.println("你的验证码为：" + smsCode + "，请在3分钟之内使用!");//可以这样测试
    }

    @Override
    public void binderSmsCode(SmsDto smsDto) {
        String phone = smsDto.getPhone();
        //1.校验
        //a.非空校验 - 3个
        if (StringUtils.isEmpty(phone)) {
            throw new BusinessException("手机号码不能为空");
        }
        //2.生成手机验证码
        //redis保存手机验证码：register:18856566636 - 9527:156336655555
        //a.从redis中获取手机验证码 - 进行判断
        Object smsObj = redisTemplate.opsForValue().get(VerifyCodeConstant.BINDER_CODE_PREFIX + phone); //9527:156336655555
        String smsCode = null;
        if (smsObj == null) {
            //a1.如果没有 = 第一次获取或手机验证码过期 -> 重新调用StrUtils创建新的手机验证码
            smsCode = StrUtils.getRandomString(6);
        } else {
            //a2.如果有 = 手机验证码过期没有过期 -> 判断重发时间【时间戳相减与1分钟】
            long nowTime = System.currentTimeMillis();
            String oldTimeTemp = smsObj.toString().split(":")[1];
            long oldTime = Long.parseLong(oldTimeTemp);
            if ((nowTime - oldTime) < 1 * 60 * 1000) {//重复发送短信验证码
                //a21.如果没有过重发时间 -> 抛业务异常【操作过于频繁，请稍后再试】
                throw new BusinessException("操作过于频繁，请稍后再试");
            } else {
                //a22.如果过了重发时间 -> 就使用以前的验证码
                smsCode = smsObj.toString().split(":")[0];
            }
        }
        //3.手机验证码保存到redis - 要不要刷新过期时间？[保存到redis要不要再次设置3分钟有效]
        redisTemplate.opsForValue().set(VerifyCodeConstant.BINDER_CODE_PREFIX + phone,
                smsCode + ":" + System.currentTimeMillis(), 3, TimeUnit.MINUTES);
        //4.调用工具类发送短信
        //SmsUtils.sendSms(phone,"你的验证码是：" + smsCode+",请在3分钟内使用!!!");
        System.out.println("你的验证码是：" + smsCode + ",请在3分钟内使用!!!");
    }
}
